package ru.spbu.math.seabattle.client.jms.gui;

import java.awt.Container;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.HashMap;
import java.util.Map;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;

import ru.spbu.math.seabattle.entity.PlayerID;

public class PlayerListComponent implements IComponent {

	private static final long 		serialVersionUID = 1L;
	private static final int		BUTTON_HEIGHT = 40;		
	
	private DefaultListModel 	playerListModel;
	private JList 				playerJList;
	private JScrollPane 		playerScrollPane = new JScrollPane(playerJList);
	private JButton 			selectPlayerButton;
	private JButton 			requestGameButton;
	private JButton 			withdrawRequestButton;
	
	private final  PlayerListGUI	playerListGui;
	
	private final Map<String, PlayerID> name2Id = new HashMap<String, PlayerID>();  

	public PlayerListComponent(PlayerListGUI gui) {
		playerListGui = 		gui;
		playerListModel = 		new DefaultListModel();
		playerJList = 			new JList(playerListModel);
		playerJList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		
		selectPlayerButton = 	new JButton("Select");
		selectPlayerButton.setVisible(true);
		requestGameButton = 	new JButton("Bid");
		requestGameButton.setVisible(true); 
		withdrawRequestButton = new JButton("Withdraw");
		withdrawRequestButton.setVisible(false);
		playerScrollPane = 		new JScrollPane(playerJList);	
		selectPlayerButton.addMouseListener(selectButtonListener);
		requestGameButton.addMouseListener(requestGameButtonListener);
		withdrawRequestButton.addMouseListener(withdrawRequestButtonListener);
		
		selectPlayerButton.setEnabled(true);
		requestGameButton.setEnabled(true);
		playerJList.setEnabled(true);
	}
	
	private void changeButton() {
		if (requestGameButton.isVisible()) {
			requestGameButton.setVisible(false);
			withdrawRequestButton.setVisible(true);
		} else {
			requestGameButton.setVisible(true);
			withdrawRequestButton.setVisible(false);
		}
	}
	
	private MouseListener selectButtonListener = new MouseListener() {

		@Override
		public void mouseClicked(MouseEvent arg0) {
			int i = playerJList.getSelectedIndex();
			if (i < 0) 
				return;
			String playerName = (String) playerListModel.get(i);
			playerListGui.onPlayerSelected(name2Id.get(playerName));
		}
		@Override public void mouseEntered(MouseEvent arg0) {}
		@Override public void mouseExited(MouseEvent arg0) {}
		@Override public void mousePressed(MouseEvent arg0) {}
		@Override public void mouseReleased(MouseEvent arg0) {}
	};
	
	private MouseListener requestGameButtonListener = new MouseListener() {

		@Override
		public void mouseClicked(MouseEvent arg0) {
			playerListGui.onApplicationPut();
			disable();
			selectPlayerButton.setEnabled(false);
			changeButton();
		}
		
		@Override public void mouseEntered(MouseEvent arg0) {}
		@Override public void mouseExited(MouseEvent arg0) {}
		@Override public void mousePressed(MouseEvent arg0) {}
		@Override public void mouseReleased(MouseEvent arg0) {}
	};
	
	private MouseListener withdrawRequestButtonListener = new MouseListener() {

		@Override
		public void mouseClicked(MouseEvent e) {
			playerListGui.onApplicationWithdrawn();
			selectPlayerButton.setEnabled(true);
			changeButton();
		}
		
		@Override public void mouseEntered(MouseEvent e) {}
		@Override public void mouseExited(MouseEvent e) {}
		@Override public void mousePressed(MouseEvent e) {}
		@Override public void mouseReleased(MouseEvent e) {}
	};
	
	public void disable() {
		playerJList.setEnabled(false);
	}
	
	public void enable() {
		playerJList.setEnabled(true);
	}
	
	public void addPlayer(String playerName, PlayerID id) {
		playerListModel.addElement(playerName);
		name2Id.put(playerName, id);
	}
	
	public void removePlayer(String playerName) {
		playerListModel.removeElement(playerName);
	}
	
	@Override
	public void addToContainer(Container container) {
		container.add(playerScrollPane);
		container.add(selectPlayerButton);
		container.add(requestGameButton);
		container.add(withdrawRequestButton);
	}

	
	@Override
	public void setBounds(Rectangle r) {
		
		if (r.height < 100 || r.width < 50) {
			throw new IllegalArgumentException("The rectangle is too small");
		}
		
		//trying to put both list and button into this rectangle. 
		//The button will be at the bottom, right under the list and will be BUTTON_HEIGHT in height.
		Rectangle paneRectangle = new Rectangle(r.x, r.y, r.width, r.height - BUTTON_HEIGHT);
		Rectangle selectButtonRectangle = new Rectangle(r.x, r.y + r.height - BUTTON_HEIGHT, (r.width-2) / 2, BUTTON_HEIGHT);
		Rectangle bidButtonRectangle = new Rectangle(r.x + (r.width - 2) / 2, r.y + r.height - BUTTON_HEIGHT, (r.width-2) / 2, BUTTON_HEIGHT);
		
		
		playerScrollPane.setBounds(paneRectangle);
		playerJList.setBounds(paneRectangle);
		selectPlayerButton.setBounds(selectButtonRectangle);
		requestGameButton.setBounds(bidButtonRectangle);
		withdrawRequestButton.setBounds(bidButtonRectangle);
	}
	
	public void setBounds(int x, int y, int width, int height) {
		this.setBounds(new Rectangle(x, y, width, height));
	}
}
